package main

import (
	"fmt"
	"net"
	"net/http"
	"strconv"
	"user/common"
	"user/domain/repository"
	"user/domain/service"
	"user/handler"
	pb "user/proto"

	"github.com/afex/hystrix-go/hystrix"
	"github.com/go-micro/plugins/v4/registry/consul"
	ratelimit "github.com/go-micro/plugins/v4/wrapper/ratelimiter/uber"
	"github.com/go-micro/plugins/v4/wrapper/select/roundrobin"
	"github.com/go-micro/plugins/v4/wrapper/trace/opentracing"
	tracer "github.com/opentracing/opentracing-go"
	"go-micro.dev/v4"
	"go-micro.dev/v4/registry"
	"go-micro.dev/v4/util/log"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)

func main() {
	// 配置中心
	consulConfig, err := common.GetConsulConfig("127.0.0.1", 8500, "/micro/config")
	if err != nil {
		log.Error(err)
	}
	// 注册中心
	consulRegistry := consul.NewRegistry(func(options *registry.Options) {
		options.Addrs = []string{
			"127.0.0.1:8500",
		}
	})
	// 链路追踪
	t, io, err := common.NewTracer("user", "localhost:6831")
	if err != nil {
		log.Error(err)
	}
	defer io.Close()
	tracer.SetGlobalTracer(t)
	hystrixStreamHandler := hystrix.NewStreamHandler()
	hystrixStreamHandler.Start()
	go func() {
		err = http.ListenAndServe(net.JoinHostPort("0.0.0.0", "9906"), hystrixStreamHandler)
		if err != nil {
			log.Error(err)
		}
	}()
	srv := micro.NewService(
		micro.Name("user"),
		micro.Version("latest"),
		micro.Address("0.0.0.0:8080"),
		micro.Registry(consulRegistry),
		micro.WrapClient(opentracing.NewClientWrapper(tracer.GlobalTracer())),
		micro.WrapClient(ratelimit.NewClientWrapper(100)),
		micro.WrapClient(roundrobin.NewClientWrapper()),
	)
	mysqlConfig := common.GetMysqlFromConsul(consulConfig, "mysql")
	srv.Init()
	dsn := mysqlConfig.User +
		":" +
		mysqlConfig.Pwd +
		"@tcp(" + mysqlConfig.Host +
		":" +
		strconv.Itoa(mysqlConfig.Port) +
		")/micro?charset=utf8mb4&parseTime=True&loc=Local"
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
	if err != nil {
		fmt.Println(err)
	}
	// rp := repository.NewUserRepository(db)
	// rp.InitTable()
	// userService := service.NewUserService(rp)
	userService := service.NewUserService(repository.NewUserRepository(db))
	pb.RegisterUserHandler(srv.Server(), &handler.User{UserService: userService})
	srv.Run()
}
